Skip to content

feat: add built-in prompts and prompt templates for agents (#1401)#1405

Merged
EItanya merged 15 commits intomainfrom
eitanya/prompt-templates
Feb 28, 2026
Merged

feat: add built-in prompts and prompt templates for agents (#1401)#1405
EItanya merged 15 commits intomainfrom
eitanya/prompt-templates

Conversation

@EItanya
Copy link
Contributor

@EItanya EItanya commented Feb 28, 2026

Add Go text/template support to the Agent CRD's systemMessage field, enabling composable prompt fragments and variable interpolation. Templates are resolved at reconciliation time by the controller.

  • Add PromptSource type using inlined TypedLocalReference for extensibility
  • Add promptSources field to DeclarativeAgentSpec
  • Implement template resolution with {{include "source/key"}} syntax and agent context variables (AgentName, AgentNamespace, Description, ToolNames, SkillNames)
  • Add ConfigMap watch to agent controller for automatic re-reconciliation
  • Ship kagent-builtin-prompts Helm ConfigMap with 5 built-in templates (skills-usage, tool-usage-best-practices, safety-guardrails, kubernetes-context, a2a-communication)
  • Add GetConfigMapData/GetSecretData utility functions
  • Add architecture documentation in docs/architecture/prompt-templates.md

Add Go text/template support to the Agent CRD's systemMessage field,
enabling composable prompt fragments and variable interpolation. Templates
are resolved at reconciliation time by the controller.

- Add PromptSource type using inlined TypedLocalReference for extensibility
- Add promptSources field to DeclarativeAgentSpec
- Implement template resolution with {{include "source/key"}} syntax and
  agent context variables (AgentName, AgentNamespace, Description,
  ToolNames, SkillNames)
- Add ConfigMap watch to agent controller for automatic re-reconciliation
- Ship kagent-builtin-prompts Helm ConfigMap with 5 built-in templates
  (skills-usage, tool-usage-best-practices, safety-guardrails,
  kubernetes-context, a2a-communication)
- Add GetConfigMapData/GetSecretData utility functions
- Add architecture documentation in docs/architecture/prompt-templates.md

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Copilot AI review requested due to automatic review settings February 28, 2026 13:15
Wrap the prompt sources list in a PromptTemplateSpec struct, changing
the CRD field from `promptSources: []` to `promptTemplate.dataSources: []`.
This groups template-related configuration under a single field and
provides a natural extension point for future template settings.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds a prompt-templating system for Agent declarative systemMessage, enabling composition from ConfigMap/Secret fragments via {{include "source/key"}} and interpolation of agent context variables at reconciliation time.

Changes:

  • Extends the Agent CRD with promptSources (PromptSource) and documents template behavior for systemMessage / systemMessageFrom.
  • Implements template resolution (include + variable context) in the Go controller translator, with unit tests.
  • Ships a Helm-installed kagent-builtin-prompts ConfigMap plus controller watch logic and utility helpers for fetching ConfigMap/Secret data.

Reviewed changes

Copilot reviewed 10 out of 10 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
helm/kagent/templates/builtin-prompts-configmap.yaml Adds Helm ConfigMap containing built-in prompt fragments.
go/internal/utils/secret.go Adds helper to fetch all Secret data as strings.
go/internal/utils/config_map.go Adds helper to fetch all ConfigMap data.
go/internal/controller/translator/agent/template.go Implements prompt source resolution, template context building, and template execution.
go/internal/controller/translator/agent/template_test.go Adds unit tests for include and interpolation behavior.
go/internal/controller/translator/agent/adk_api_translator.go Integrates template resolution into system message translation.
go/internal/controller/agent_controller.go Adds ConfigMap watch to re-reconcile affected agents.
go/api/v1alpha2/agent_types.go Adds PromptSource type and promptSources to the declarative spec.
go/api/v1alpha2/zz_generated.deepcopy.go Updates generated deepcopy logic for the new API fields/types.
docs/architecture/prompt-templates.md Adds architecture/design documentation for prompt templates.
Comments suppressed due to low confidence (1)

go/api/v1alpha2/agent_types.go:187

  • PromptSource inlines TypedLocalReference, which includes an optional namespace field. Unless cross-namespace prompt sourcing is an explicit, access-controlled feature, this should be constrained (e.g., disallow setting namespace or require it to match the Agent namespace via XValidation). Otherwise, users can point agents at ConfigMaps/Secrets in other namespaces, and the controller’s broad RBAC will allow those reads.
	Context *ContextConfig `json:"context,omitempty"`
}

// ContextConfig configures context management for an agent.
type ContextConfig struct {
	// Compaction configures event history compaction.
	// When enabled, older events in the conversation are compacted (compressed/summarized)
	// to reduce context size while preserving key information.
	// +optional
	Compaction *ContextCompressionConfig `json:"compaction,omitempty"`
}

// ContextCompressionConfig configures event history compaction/compression.
type ContextCompressionConfig struct {
	// The number of *new* user-initiated invocations that, once fully represented in the session's events, will trigger a compaction.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

EItanya and others added 6 commits February 28, 2026 13:28
Tests the full flow: creating a ConfigMap with prompt fragments,
creating an Agent with promptTemplate.dataSources referencing it,
verifying the agent reaches Ready state, and confirming that a
ConfigMap update triggers re-reconciliation while the agent remains
functional.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Refactor all 10 agent helm charts to use the new promptTemplate feature,
replacing repeated safety, operational, and tool-usage sections with
includes from the kagent-builtin-prompts ConfigMap.

Changes per agent:
- k8s, helm: replaced Investigation Protocol, Safety Protocols, added
  tool-usage-best-practices
- cilium-debug, cilium-manager: replaced Operational Protocol, Safety
  Guidelines
- istio: replaced Operational Protocol, Safety Guidelines
- kgateway: added safety-guardrails include
- observability: replaced Operational Guidelines with kubernetes-context
  and tool-usage-best-practices
- cilium-policy, argo-rollouts, promql: added minimal includes while
  preserving domain-specific reference material

Also enhanced the built-in prompts ConfigMap with more substantive content
based on patterns observed across all agents.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
- Replace sort.Strings with slices.Sort (sort package forbidden by depguard)
- Remove Go template syntax ({{ }}) from CRD doc comments to prevent
  Helm from interpreting them as template directives during CRD installation
- Regenerate CRD manifests and copy to helm chart

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
1. Drop Secret support from prompt sources — only ConfigMaps are
   supported to avoid security risks of referencing Secrets.
2. Adapt to TypedLocalReference (no namespace field) for PromptSource
   since prompt sources must be in the same namespace as the agent.
3. Move template resolution after the tool translation loop so tool
   names come from the already-built AgentConfig rather than being
   recomputed from the spec.
4. Use existing ociSkillName()/gitSkillName() helpers for skill name
   extraction instead of duplicating parsing logic.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
@EItanya EItanya requested a review from peterj as a code owner February 28, 2026 14:13
EItanya and others added 5 commits February 28, 2026 14:38
Fix k8s, helm, cilium-debug, cilium-manager, and cilium-policy agents
that had the wrong YAML structure — using an array with configMapRef
directly under promptTemplate instead of the correct dataSources object
with kind: ConfigMap entries.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
supreme-gg-gg
supreme-gg-gg previously approved these changes Feb 28, 2026
Copy link
Contributor

@supreme-gg-gg supreme-gg-gg left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Tried this out very cool

)

// GetSecretData fetches all data from a Secret, converting byte values to strings.
func GetSecretData(ctx context.Context, c client.Client, ref client.ObjectKey) (map[string]string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This does not seem to be used anywhere?


// resolvePromptSources fetches all data from the referenced ConfigMaps and builds
// a lookup map keyed by "identifier/key" where identifier is the alias (if set) or resource name.
func resolvePromptSources(ctx context.Context, kube client.Client, namespace string, sources []v1alpha2.PromptSource) (map[string]string, error) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nit: since we only support configmaps kind, should we validate the PromptSource.Kind and give an error if the user tries to provide a secret?

Signed-off-by: Eitan Yarmush <eitan.yarmush@solo.io>
@EItanya EItanya merged commit 05d0bde into main Feb 28, 2026
37 of 38 checks passed
@EItanya EItanya deleted the eitanya/prompt-templates branch February 28, 2026 22:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants